#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libubox/usock.h>
#include <libubox/uloop.h>

static void client_cb(struct uloop_fd *u, unsigned int events)
{
    char buf[1024] = {0};

	printf("recieve client write\n");
    if (events & ULOOP_READ) {
        if ( recv(u->fd, buf, 1024, 0) > 0) {
            printf("from client recv_buf: %s\n", buf);
            send(u->fd, "hello world from server", strlen("helloworld from server"), 0);
        }
    }
}

static void server_cb(struct uloop_fd *u, unsigned int events)
{
	int new_fd;
	struct uloop_fd *client_fd;

	printf("recieve new conncet\n");

	new_fd = accept(u->fd, NULL, 0);
	if (new_fd < 0) {
		switch (errno) {
		case ECONNABORTED:
		case EINTR:
			return true;
		default:
			return false;
		}
	}

	client_fd = (struct uloop_fd *)malloc(sizeof(*client_fd));
	client_fd->fd = new_fd;
	client_fd->cb = client_cb;

	uloop_fd_add(client_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER);

	return;
}

int main()
{
    int type = USOCK_TCP | USOCK_SERVER  | USOCK_NOCLOEXEC | USOCK_IPV4ONLY;
    const char *host = "127.0.0.1";
    const char *service = "8888";

    int u_fd = usock(type, host, service);
    if (u_fd < 0) {
        printf("usock error!!!\n");

        return -1;
    }

    struct uloop_fd fd[1] = {
        {
            .cb = server_cb,
            .fd = u_fd,
        }
    };

    uloop_init();

    /*添加uloop_fd*/
    uloop_fd_add(&fd[0], ULOOP_READ | ULOOP_EDGE_TRIGGER);

    printf("start run \n\n");

    uloop_run();

    printf("end\n\n");

    uloop_fd_delete(&fd[0]);

    uloop_done();

    return 0;
}
